﻿using System;


namespace DailyFx
{

	public interface IIndex : IMatrix
	{

		/// <summary>
		///		Gets Family (Category) of this <see cref="IIndex"/>.
		/// </summary>
		String Family { get; }

		/// <summary>
		///		Gets label text to display .
		/// </summary>
		String Label { get; }


		/// <summary>
		///		Gets or sets previous bar items required, Mainly for MA types . 
		/// </summary>
		// Int32 Span { get; set; }

		/// <summary>
		///		Gets how many child component holded by this <see cref="IIndex"/>.
		/// </summary>
		// Int32 Rank { get; }




		/// <summary>
		///		Runs through entire <see cref="BarSeries"/>, 
		///		 to cook for this type of <see cref="Index"/> via specific formula .
		/// </summary>
		void Cook ( BarSeries series );


		/// <summary>
		///		Gets the child at given radix
		/// </summary>
		new HyperVector this [ int radix ]  { get; }

		/// <summary>
		///		Gets the child by given label .
		/// </summary>
		HyperVector this [ string label ]  { get; }
	}


	public abstract class Index : IIndex
	{
		/// <summary>
		///		the available child' components .
		/// </summary>
		protected readonly HyperVector[] _children;

		/// <summary>
		///		How many elements of each child component .
		/// </summary>
		protected Int32 _length;


		/// <summary>
		///     c'tor
		/// </summary>
		protected Index ( int rank, int length )
		{
			this._children = new HyperVector[rank];
			this._length = length;

			// for (int r = 0; r < rank; ++r)
			// {
			// }

			// Cook() ;
		}


		/// <summary>
		///		Runs through entire <see cref="BarSeries"/>, 
		///		to cook for this type of <see cref="IIndex"/> via specific formulas
		/// </summary>
		public abstract void Cook ( BarSeries series );
		// {
		// Not yet detailed ...
		// }



		//
		public decimal this[int radix, int i]
		{
			get
			{
				// assert ( radix >= 0 && radix < Rank )
				return this._children[radix][i];
			}
			set
			{
				this._children[radix][i] = value;
			}
		}

		//
		public HyperVector this[int index]
		{
			get
			{
				return _children[index];
			}
		}

		IVector IMatrix.this[int row]
		{
			get
			{
				return _children[row];
			}
		}

		//
		public virtual HyperVector this[String label]
		{
			get
			{
				for (int r = 0; r < this.Rank; ++r)
				{
					if (_children[r].Label == label)
						return _children[r];
				}
				return null;
			}
		}


		/// <summary>
		///		Gets the Family(Category) of this .
		/// </summary>
		public abstract string Family
		{
			get;
		}

		/// <summary>
		///		Gets the label text to display .
		/// </summary>
		public abstract string Label
		{
			get;
		}


		//
		public virtual int Rank
		{
			get { return _children.Length; }
		}
		//
		public int Length // use with caution .
		{
			get
			{
				return this._length;
			}
		}


	}


}
